package com.jneagle.xlstool.bzwgjmx.view.gui;

import com.dwarfeng.dutil.basic.cna.model.ReferenceModel;
import com.dwarfeng.dutil.basic.cna.model.obs.ReferenceAdapter;
import com.dwarfeng.dutil.basic.gui.swing.SwingUtil;
import com.jneagle.xlstool.bzwgjmx.view.handler.I18nHandler;
import com.jneagle.xlstool.bzwgjmx.view.structure.OperationStep;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Body 位置的 TabbedPane
 *
 * @author DwArFeng
 * @since 1.0.0
 */
@Component
@DependsOn("viewConfiguration")
public class BodyTabbedPane extends JTabbedPane {

    private static final long serialVersionUID = -6966055301972934679L;

    private final I18nHandler i18nHandler;

    private final ReferenceModel<OperationStep> operationStepModel;

    private final StructuredDataImportPanel structuredDataImportPanel;
    private final RawDataImportPanel rawDataImportPanel;
    private final DataConfirmPanel dataConfirmPanel;
    private final DataExportPanel dataExportPanel;

    private final OperationStepObserver operationStepObserver = new OperationStepObserver();
    private final InnerChangeListener innerChangeListener = new InnerChangeListener();

    public BodyTabbedPane(
            I18nHandler i18nHandler,
            @Qualifier("operationStepModel") ReferenceModel<OperationStep> operationStepModel,
            StructuredDataImportPanel structuredDataImportPanel,
            RawDataImportPanel rawDataImportPanel,
            DataConfirmPanel dataConfirmPanel,
            DataExportPanel dataExportPanel
    ) {
        this.i18nHandler = i18nHandler;
        this.operationStepModel = operationStepModel;
        this.structuredDataImportPanel = structuredDataImportPanel;
        this.rawDataImportPanel = rawDataImportPanel;
        this.dataConfirmPanel = dataConfirmPanel;
        this.dataExportPanel = dataExportPanel;
    }

    @PostConstruct
    public void postConstruct() {
        // 初始化界面。
        add(i18nHandler.getMessage("ui.label.000"), structuredDataImportPanel);
        add(i18nHandler.getMessage("ui.label.001"), rawDataImportPanel);
        add(i18nHandler.getMessage("ui.label.002"), dataConfirmPanel);
        add(i18nHandler.getMessage("ui.label.003"), dataExportPanel);
        // 添加侦听器。
        addChangeListener(innerChangeListener);
        operationStepModel.addObserver(operationStepObserver);
        // 同步属性。
        syncProperties();
    }

    private void syncProperties() {
        SwingUtil.invokeInEventQueue(() -> {
            switch (operationStepModel.get()) {
                case STRUCTURED_DATA_IMPORT:
                    setEnabledAt(0, true);
                    setEnabledAt(1, false);
                    setEnabledAt(2, false);
                    setEnabledAt(3, false);
                    break;
                case RAW_DATA_IMPORT:
                    setEnabledAt(0, true);
                    setEnabledAt(1, true);
                    setEnabledAt(2, false);
                    setEnabledAt(3, false);
                    break;
                case DATA_CONFIRM:
                    setEnabledAt(0, true);
                    setEnabledAt(1, true);
                    setEnabledAt(2, true);
                    setEnabledAt(3, false);
                    break;
                case DATA_EXPORT:
                    setEnabledAt(0, true);
                    setEnabledAt(1, true);
                    setEnabledAt(2, true);
                    setEnabledAt(3, true);
                    break;
            }
        });
    }

    @PreDestroy
    public void preDestroy() {
        // 移除侦听器。
        removeChangeListener(innerChangeListener);
        operationStepModel.removeObserver(operationStepObserver);
    }

    private final class OperationStepObserver extends ReferenceAdapter<OperationStep> {

        @Override
        public void fireSet(OperationStep oldValue, OperationStep newValue) {
            SwingUtil.invokeInEventQueue(() -> {
                switch (newValue) {
                    case STRUCTURED_DATA_IMPORT:
                        setEnabledAt(0, true);
                        setEnabledAt(1, false);
                        setEnabledAt(2, false);
                        setEnabledAt(3, false);
                        break;
                    case RAW_DATA_IMPORT:
                        setEnabledAt(0, true);
                        setEnabledAt(1, true);
                        setEnabledAt(2, false);
                        setEnabledAt(3, false);
                        break;
                    case DATA_CONFIRM:
                        setEnabledAt(0, true);
                        setEnabledAt(1, true);
                        setEnabledAt(2, true);
                        setEnabledAt(3, false);
                        break;
                    case DATA_EXPORT:
                        setEnabledAt(0, true);
                        setEnabledAt(1, true);
                        setEnabledAt(2, true);
                        setEnabledAt(3, true);
                        break;
                }
            });
        }
    }

    private class InnerChangeListener implements ChangeListener {

        @Override
        public void stateChanged(ChangeEvent e) {
            switch (getSelectedIndex()) {
                case 0:
                    structuredDataImportPanel.loadData();
                    break;
                case 1:
                    rawDataImportPanel.loadData();
                    break;
                case 2:
                    dataConfirmPanel.loadData();
                    break;
                case 3:
                    dataExportPanel.loadData();
                    break;
            }
        }
    }
}
